package com.well.register.netty.handle;

import com.alibaba.fastjson.JSONObject;
import com.well.register.data.DataCenter;
import com.well.register.event.AppEvent;
import com.well.register.event.EventContext;
import com.well.register.netty.ConnClusterClient;
import com.well.rpc.model.ClusterServerModel;
import com.well.rpc.model.EventType;
import com.well.rpc.model.TransData;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.well.register.util.ValidateUtils;

import java.net.SocketAddress;
import java.text.SimpleDateFormat;
import java.util.Date;

public class ClusterConnHandle extends SimpleChannelInboundHandler<TransData> {
    Logger logger = LoggerFactory.getLogger(ClusterConnHandle.class);

    private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:dd");
    TransData heartBeat = new TransData(EventType.HEARTBEAT, "heartBeat");
    SocketAddress socketAddress = null;
    Boolean isConnect = false;


    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, TransData transData) throws Exception {
        AppEvent eventByType = EventContext.getEventByType(transData.getType());
        eventByType.doEvent(channelHandlerContext, transData);
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        if (evt instanceof IdleStateEvent) {
            socketAddress = ctx.channel().remoteAddress();
            IdleState state = ((IdleStateEvent) evt).state();
            if (state == IdleState.WRITER_IDLE) {
                if (!isConnect) {
                    isConnect = true;
                    ctx.writeAndFlush(checkCluster(ValidateUtils.getIp(socketAddress)));
                } else {
                    ctx.writeAndFlush(heartBeat);
                }
            }
        } else {
            super.userEventTriggered(ctx, evt);
        }
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        super.channelInactive(ctx);
        logger.info("客户端与服务端断开连接,断开的时间为：" + format.format(new Date()));
        ctx.close();
        if (socketAddress != null) {
            ConnClusterClient.run(socketAddress);
        }
    }

    public static TransData checkCluster(String target) {
        TransData transData = new TransData();
        transData.setType(EventType.CHECK_CLUSTER);
        ClusterServerModel serverModel = new ClusterServerModel();
        serverModel.setPort(DataCenter.getPort());
        serverModel.setAge(DataCenter.getStartTime());
        serverModel.setIsUp(true);
        serverModel.setTargetHost(target);
        transData.setJsonData(JSONObject.toJSONString(serverModel));
        return transData;
    }
}
